package com.jiumi.api.util;

import cn.hutool.core.map.MapUtil;
import cn.hutool.json.JSONUtil;
import com.jiumi.common.core.redis.RedisCache;
import com.jiumi.common.utils.StringUtils;
import com.jiumi.config.WeiXinConfig;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import okhttp3.*;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author lun.zhang
 * @create 2022/10/18 11:02
 */
@Component
public class WeiXinUtil {

    @Autowired
    private RedisCache redisCache;
    @Autowired
    private WeiXinConfig weiXinConfig;
    private static Logger logger = LoggerFactory.getLogger(WeiXinUtil.class);
    public static Map<String, Object> getWxUserOpenId(String code, String appId, String appSecret) {
        //拼接url
        StringBuilder url = new StringBuilder("https://api.weixin.qq.com/sns/jscode2session?");
        //appid设置
        url.append("appid=");
        url.append(appId);
        //secret设置
        url.append("&secret=");
        url.append(appSecret);
        //code设置
        url.append("&js_code=");
        url.append(code);
        url.append("&grant_type=authorization_code");
        Map<String, Object> map = null;
        try {
            //构建一个Client
            HttpClient client = HttpClientBuilder.create().build();
            //构建一个GET请求
            HttpGet get = new HttpGet(url.toString());
            //提交GET请求
            HttpResponse response = client.execute(get);
            //拿到返回的HttpResponse的"实体"
            HttpEntity result = response.getEntity();
            String content = EntityUtils.toString(result);
            //打印返回的信息
            //把信息封装为json
            JSONObject res = JSONObject.parseObject(content);
            //把信息封装到map
            map = parseJSON2Map(res);
        } catch (Exception e) {
            logger.info("获取openId失败:%s", e.getMessage());
        }
        return map;
    }
    public static Map<String, Object> parseJSON2Map(JSONObject json) {
        Map<String, Object> map = new HashMap<String, Object>();
        // 最外层解析
        for (Object k : json.keySet()) {
            Object v = json.get(k);
            // 如果内层还是数组的话，继续解析
            if (v instanceof JSONArray) {
                List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
                @SuppressWarnings("unchecked")
                Iterator it = ((JSONArray) v).iterator();
                while (it.hasNext()) {
                    JSONObject json2 = (JSONObject) it.next();
                    list.add(parseJSON2Map(json2));
                }
                map.put(k.toString(), list);
            } else {
                map.put(k.toString(), v);
            }
        }
        return map;
    }

    public  JSONObject getWxPhoneNumber(String code){
        Map<String, Object> res = getAccessToken();
        String accessToken = (String) res.get("access_token");
        String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token="+accessToken ;
        Map<String,String> data = new HashMap<>();
        data.put("code",code);
        OkHttpClient okHttpClient = new OkHttpClient();
        MediaType parse = MediaType.parse("application/json; charset=utf-8");

        RequestBody form = RequestBody.create(parse, JSONUtil.toJsonStr(data));
        Request request = new Request.Builder()
                .url(url)
                .post(form)
                .build();
        try {
            Response response = okHttpClient.newCall(request).execute();
            String string = response.body().string();
            if(StringUtils.isEmpty(string)){
                return null;
            }
            JSONObject jsonObject = JSONObject.parseObject(string);
            JSONObject phone_info =(JSONObject) jsonObject.get("phone_info");
            phone_info.remove("watermark");
            return phone_info;
        } catch (IOException e) {
            logger.error("获取手机号失败：{}",e.getMessage());
            throw new RuntimeException(e);
        }
    }


    public  Map<String, Object> getAccessToken() {
        Map<String, Object> access_token = redisCache.getCacheMap("access_token");
        if (StringUtils.isNotNull(access_token) && MapUtil.isNotEmpty(access_token)) {
            return access_token;
        }
        //拼接url
        StringBuilder url = new StringBuilder("https://api.weixin.qq.com/cgi-bin/token?");
        //appid设置
        url.append("grant_type=");
        url.append("client_credential");
        //secret设置
        url.append("&appid=");
        url.append(weiXinConfig.getAppId());
        //code设置
        url.append("&secret=");
        url.append(weiXinConfig.getAppSecret());
        Map<String, Object> map = null;
        try {
            //构建一个Client
            HttpClient client = HttpClientBuilder.create().build();
            //构建一个GET请求
            HttpGet get = new HttpGet(url.toString());
            //提交GET请求
            HttpResponse response = client.execute(get);
            //拿到返回的HttpResponse的"实体"
            HttpEntity result = response.getEntity();
            String content = EntityUtils.toString(result);
            //打印返回的信息
//            System.out.println(content);
            //把信息封装为json
            JSONObject res = JSONObject.parseObject(content);
            //把信息封装到map
            map = parseJSON2Map(res);
            redisCache.setCacheMap("access_token", map);
            Integer expiresIn = (Integer) map.get("expires_in");
            int expire = expiresIn - 200;

            boolean flag = redisCache.expire("access_token", Long.valueOf(expire), TimeUnit.SECONDS);
            if (!flag) {
                redisCache.deleteObject("access_token");
            }


        } catch (Exception e) {
            logger.info("获取getAccessToken失败:{}", e.getMessage());
        }
        return map;
    }
}
